package ClientPackage;

import java.io.IOException;
import java.net.*;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.util.Random;

import SecureUtil.CookieHelper;
import SecureUtil.DiffieHellman;
import SecureUtil.Packer;
import SecureUtil.UDPHelper;
import SecureUtil.Packer.DataType;

/**
 * This class services the Client for waiting to receive any data packet from
 * the server or other clients.
 * 
 * @author Zhisheng Huang
 */
public class ClientReceiveThread implements Runnable {

	private DatagramSocket _clientSocket;
	private PrivateKey _clientPrivKey;
	
	private static int cookieseed = new Random().nextInt();

	public ClientReceiveThread(DatagramSocket datagramSocket, PrivateKey clientPrivKey) {
		_clientSocket = datagramSocket;
		_clientPrivKey = clientPrivKey;
	} // End constructor

	public void run() {

		while (true) {

			try {

				//This socket is the only socket that used to listen to any incoming request
				//No matter from server or other clients
				UDPHelper udphelper = new UDPHelper(_clientSocket);
				byte[] receiveByte = udphelper.receiveBytes(0);
				String cookieToSend = null;
		
				Packer packer = new Packer();
				packer.unpack(receiveByte);
				String s1 = (String)packer.getNext(Packer.DataType.STRING);
				String s2 = (String)packer.getNext(Packer.DataType.STRING);	//s2 suppose to be cookie			
				packer.Reset();

				if (s1.equalsIgnoreCase("request") && s2.equalsIgnoreCase("")) {
					cookieToSend 
					= CookieHelper.getCookie(udphelper.fromip, udphelper.fromport, cookieseed);
					
					//send back cookie
					udphelper.sendBytes(cookieToSend.getBytes(), udphelper.fromip, udphelper.fromport);
					System.out.println("request without cookie, sent back a cookie.");				
				} else if (s1.equalsIgnoreCase("request2")
						&& s2.equals(CookieHelper.getCookie(udphelper.fromip, udphelper.fromport, cookieseed))){
					
					//In this situation, we spawn a new thread and change another socket to 
					//communicate.
					
					ClientInfo receiveClientInfo = Client.getInstance().searchOnlineByAddress(udphelper.fromip);
					DatagramSocket newSocketForAuthenticate = new DatagramSocket();
					
					new Thread(new ClientAuthenticateThread(receiveClientInfo, newSocketForAuthenticate, _clientPrivKey,udphelper.fromip, udphelper.fromport )).start();
					System.out.println("request2 with cookie and cookie is correct, open a new thread...");
				} else if(s1.equalsIgnoreCase("listFromServer")) {
					
					
				} else {
					
				}

			} catch (IOException e) {
				System.out
						.println("Error happens when receiving data from server....");
				e.printStackTrace();
			} // End catch
			catch (Exception e) {
				// TODO Auto-generated catch block
				System.out.println("interrupt.");
				e.printStackTrace();
			}

		}// End while

	} // End run

} // End class receiveThread
